<?php

class Out
{
    public static $page;
    public static $action;
    public static $cid;
    public static $sid;

    /*页面*/
    public static function Page($rule, $fn)
    {
        if (isset($rule[HTTP_PAGE])) {
            isset($_GET['cid']) || self::Error("cid不能为空");
            isset($_GET['sid']) || self::Error("sid不能为空");
            self::$cid  = $_GET['cid'];
            self::$sid  = $_GET['sid'];
            self::$page = $rule[HTTP_PAGE];
            $fn();
        }
    }
    /*操作*/
    public static function Action($rule, $fn)
    {
        if (isset($rule[HTTP_ACTION])) {
            self::$action = $rule[HTTP_ACTION];
            $data         = $fn(self::$cid, self::$sid, HTTP_PAGE, HTTP_ACTION);
            Sys::$conf['LOG'] && self::Log();
            self::Json($data);
        }
    }
    /*输出接口*/
    public static function Api($rule, $fn)
    {
        if (HTTP_PAGE == $rule) {
            $data = $fn();
            self::Json($data);
        }
    }
    /*写入日志*/
    public static function Log()
    {
        $table = Sys::$conf['LOG_TABLE'];
        $sql   = <<<EOT
        CREATE TABLE IF NOT EXISTS `{$table}` (
          `id` int(11) NOT NULL AUTO_INCREMENT,
          `site` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '站点',
          `page` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '页面',
          `action` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '操作',
          `visitor` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '访客',
          `con_id` int(11) DEFAULT NULL COMMENT '主内容ID',
          `son_id` int(11) DEFAULT NULL COMMENT '子内容ID',
          `ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'IP',
          `client` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '客户端',
          `data` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '数据',
          `add_time` int(11) DEFAULT NULL COMMENT '添加时间',
          PRIMARY KEY (`id`),
          KEY `id` (`id`) USING BTREE,
          KEY `a` (`page`,`action`,`visitor`,`con_id`),
          KEY `b` (`page`,`action`,`con_id`) USING BTREE,
          KEY `c` (`site`,`page`,`action`,`con_id`) USING BTREE,
          KEY `d` (`site`,`page`,`action`,`con_id`,`son_id`) USING BTREE,
          KEY `e` (`page`,`action`,`con_id`) USING BTREE,
          KEY `f` (`page`,`action`,`con_id`,`son_id`) USING BTREE,
          KEY `add_time` (`add_time`,`son_id`,`con_id`,`page`,`action`)
        ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='操作记录表';
        EOT;
        Data::Sql($sql);
        $time = time();
        $ip   = self::GetClientIP();
        $uid  = Session::Get("id", $ip);
        $sql  = [
            "table" => $table,
            "set"   => [
                "site"     => Sys::$conf['SITE_NAME'],
                "page"     => self::$page,
                "action"   => self::$action,
                "visitor"  => $uid,
                "con_id"   => preg_match("/^[0-9]+$/", self::$cid) ? self::$cid : 0,
                "son_id"   => self::$sid,
                "data"     => json_encode($_GET),
                "ip"       => $ip,
                "client"   => $_SERVER["HTTP_USER_AGENT"],
                "add_time" => $time,
            ],
        ];
        Data::Insert($sql);
        if (self::$action == '登录') {
            Data::Sql("UPDATE {$table} SET visitor = '{$uid}' WHERE visitor = '{$ip}'");
        }
    }
    /*获取客户端IP*/
    public static function GetClientIP()
    {
        if (getenv("HTTP_CLIENT_IP")) {
            $ip = getenv("HTTP_CLIENT_IP");
        } else if (getenv("HTTP_X_FORWARDED_FOR")) {
            $ip = getenv("HTTP_X_FORWARDED_FOR");
        } else if (getenv("REMOTE_ADDR")) {
            $ip = getenv("REMOTE_ADDR");
        } else {
            $ip = "Unknow";
        }
        return $ip;
    }
    /*输出JSON*/
    public static function Json($data)
    {
        header('Content-type: text/json');
        if (empty($data) || !isset($data['state']) || !isset($data['msg'])) {
            $data = ["state" => "ok", "msg" => "操作成功", "data" => $data];
        }
        self::DataFormat($data);
        $json = json_encode($data);
        die($json);
    }
    /*输出异常*/
    public static function Error($msg, $state = 'error')
    {
        header('Content-type: text/json');
        die(json_encode(['state' => $state, 'msg' => $msg]));
    }
    /*数据格式化*/
    public static function DataFormat(&$data)
    {
        if (!is_array($data)) {
            return ($value == '' || $value == 'null') && $data = null;
        }
        foreach ($data as $key => $value) {
            (is_array($value) && sizeof($value) <= 0) && $data[$key] = null;
            ($value == '' || $value == 'null') && $data[$key]        = null;
            is_array($value) && self::DataFormat($data[$key]);
        }
    }
}
